#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# cron: 49 23 * * *
# new Env("阅读本每日统计报告")
import os
import re
import sys
import glob
import requests
from datetime import datetime, timedelta

# ========== 配置区域 ==========
PUSH_PLUS_TOKEN = os.getenv("PUSH_PLUS_TOKEN")
SCRIPT_NAME = "阅读本每日"
LOG_DIR = "/ql/data/log/WXyuedu_*"

# 应用匹配规则 (必须配置)
APP_NAMES = [
    (r"拾米阅读", "拾米阅读"),
    (r"傻狗阅读", "傻狗阅读"), 
    (r"壹点联盟", "壹点联盟"),
    (r"元宝阅读", "元宝阅读"),
    (r"鱼儿阅读", "鱼儿阅读"),
    (r"九九联盟", "九九联盟"),
    (r"叮叮联盟", "叮叮联盟"),
    (r"多多赚宝", "多多赚宝"),
    (r"可乐阅读", "可乐阅读"),
    (r"猫猫阅读", "猫猫阅读"),
    (r"美添赚", "美添赚"),
    (r"有米赚", "有米赚"),
    (r"点点赚", "点点赚"),
    (r"小阅阅", "小阅阅"),
    (r"百事通", "百事通")
]
# =============================

class EarningsAnalyzer:
    def __init__(self):
        self.analysis_start = datetime.now()
        self.time_threshold = self.analysis_start - timedelta(hours=24)
        self.stats = {}
        self.log_dirs = self.get_log_paths()
        self._log("✅ 初始化完成")

    def _log(self, message, icon="ℹ️"):
        timestamp = datetime.now().strftime("%H:%M:%S")
        print(f"{icon} [{timestamp}] {message}", flush=True)

    def get_app_name(self, dir_name):
        """严格匹配应用名称"""
        for pattern, name in APP_NAMES:
            if re.search(pattern, dir_name, re.IGNORECASE):
                return name
        return None

    def get_log_paths(self):
        """直接使用配置的日志路径"""
        matched_dirs = sorted(glob.glob(LOG_DIR), key=os.path.getmtime, reverse=True)
        if not matched_dirs:
            self._log("⚠️ 未找到匹配的日志目录", "❌")
            sys.exit(1)
        self._log(f"📂 找到 {len(matched_dirs)} 个日志目录")
        return matched_dirs

    def convert_balance(self, raw_value, app_name):
        """增强金额转换逻辑"""
        try:
            value = float(raw_value)
            conversion_rules = {
                "壹点联盟": 1000,    # 460 → 0.46
                "点点赚": 10000,     # 7660 → 0.766
                "美添赚": 1000,     
                "可乐阅读": 1000,    
                "多多赚宝": 1       
            }
            divisor = conversion_rules.get(app_name, 1)
            return round(value / divisor, 3 if app_name == "点点赚" else 2)
        except:
            return 0.0

    def process_log(self, file_path, app_name):
        """处理单个日志文件"""
        try:
            with open(file_path, "r", encoding="utf-8") as f:
                current_account = None
                for line in f:
                    # 账号检测
                    if "开始运行" in line and (match := re.search(r"===> \[(.*?)\]", line)):
                        current_account = match.group(1).strip()
                        key = (current_account, app_name)
                        
                        if key not in self.stats:
                            self.stats[key] = {
                                "runs": 0,
                                "first_balance": None,
                                "last_balance": 0.0,
                                "withdraw": 0.0
                            }
                        self.stats[key]["runs"] += 1

                    # 余额检测（支持更多格式）
                    if current_account:
                        balance_match = re.search(
                            r"(当前余额|余额:|账号余额约|剩余积分:)\[?(\d+\.?\d*)\]?", line
                        ) or re.search(r"余额:(\d+\.\d+)", line)
                        
                        if balance_match:
                            converted = self.convert_balance(balance_match.group(2), app_name)
                            data = self.stats[(current_account, app_name)]
                            if data["first_balance"] is None:
                                data["first_balance"] = converted
                            data["last_balance"] = converted

                    # 提现检测（增强多多赚宝支持）
                    if current_account and "提现" in line:
                        withdraw_match = re.search(
                            r"提现(?:成功|\[?(\d+\.?\d*)元?\]?|金额:(\d+\.\d+))", line
                        )
                        if withdraw_match:
                            amount = 0.3  # 默认提现金额
                            if withdraw_match.group(1):  # 提现[0.3元]格式
                                amount = float(withdraw_match.group(1))
                            elif withdraw_match.group(2):  # 提现金额:0.3格式
                                amount = float(withdraw_match.group(2))
                            
                            self.stats[(current_account, app_name)]["withdraw"] += amount

        except Exception as e:
            self._log(f"⚠️ 文件解析失败: {os.path.basename(file_path)} - {str(e)}")

    def analyze_directory(self, dir_path):
        """分析单个目录"""
        dir_name = os.path.basename(dir_path)
        app_name = self.get_app_name(dir_name)
        
        if not app_name:
            self._log(f"⏭ 跳过目录: {dir_name}")
            return

        self._log(f"🔍 正在处理: {app_name}")
        
        for fname in os.listdir(dir_path):
            if not fname.endswith(".log"):
                continue

            # 精确时间过滤（支持两种文件名格式）
            try:
                file_time = datetime.strptime(fname[:19], "%Y-%m-%d-%H-%M-%S")
            except ValueError:
                try:
                    file_time = datetime.strptime(fname[:10], "%Y-%m-%d")
                except:
                    file_time = None
            
            if file_time and file_time < self.time_threshold:
                continue

            self.process_log(os.path.join(dir_path, fname), app_name)

    def generate_report(self):
        """生成带序号和小计的统计报告"""
        report = [
            "# 分应用账号统计报告",
            f"**统计时间**: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}",
            f"**分析时段**: 最近24小时（{self.time_threshold.strftime('%Y-%m-%d %H:%M')} 至 {datetime.now().strftime('%Y-%m-%d %H:%M')}）",
            ""
        ]

        grouped_data = {name: [] for _, name in APP_NAMES}
        total_final_balance = 0.0
    
        for (account, app_name), data in self.stats.items():
            if app_name in grouped_data:
                grouped_data[app_name].append((account, data))
                total_final_balance += data["last_balance"]

        for app_name in [name for _, name in APP_NAMES]:
            entries = grouped_data.get(app_name, [])
            if not entries:
                continue
            
            report.append(f"## {app_name}")
            report.append("| 序号 | 账号 | 运行次数 | 首次余额 | 最后余额 | 总提现 | 异常标记 |")
            report.append("|-----|------|---------|---------|---------|-------|----------|")
        
            app_first_total = 0.0
            app_last_total = 0.0
            app_withdraw_total = 0.0
            serial_number = 1
        
            for account, data in sorted(entries, key=lambda x: x[0]):
                is_abnormal = (
                    data["first_balance"] is not None and
                    abs(data["first_balance"] - data["last_balance"]) < 0.001 and
                    data["first_balance"] > 0
                )
            
                if data["first_balance"] is not None:
                    app_first_total += data["first_balance"]
                app_last_total += data["last_balance"]
                app_withdraw_total += data["withdraw"]
            
                report.append(
                    f"| {serial_number} "
                    f"| {account} "
                    f"| {data['runs']} "
                    f"| ¥{data['first_balance'] or 0:.2f} "
                    f"| ¥{data['last_balance']:.2f} "
                    f"| ¥{data['withdraw']:.2f} "
                    f"| {'⚠️' if is_abnormal else ''} |"
                )
                serial_number += 1
        
            report.append(
                "| **小计** | "
                f"**{sum(d[1]['runs'] for d in entries)}** | "
                f"**¥{app_first_total:.2f}** | "
                f"**¥{app_last_total:.2f}** | "
                f"**¥{app_withdraw_total:.2f}** | "
                "** ** |"
            )
            report.append("")

        total_runs = sum(v["runs"] for v in self.stats.values())
        total_withdraw = sum(v["withdraw"] for v in self.stats.values())
        abnormal_count = sum(
            1 for v in self.stats.values() 
            if v["first_balance"] and 
            abs(v["first_balance"] - v["last_balance"]) < 0.001 and
            v["first_balance"] > 0
        )
    
        report.append("## 全局汇总")
        report.append(
            f"- 总运行次数: {total_runs} 次\n"
            f"- 最后余额总计: ¥{total_final_balance:.2f}\n"
            f"- 总提现金额: ¥{total_withdraw:.2f}\n"
            f"- 异常账号: {abnormal_count} 个"
        )
        return "\n".join(report)

    def run(self):
        """主运行流程"""
        try:
            if not self.log_dirs:
                self._log("💥 未找到有效日志目录")
                return

            self._log(f"🔍 开始扫描 {len(self.log_dirs)} 个目录")
            for dir_path in self.log_dirs:
                self.analyze_directory(dir_path)

            report = self.generate_report()
            self._log("📊 完整统计报告：")
            for line in report.split("\n"):
                self._log(f"   {line}", icon="  ")

            if PUSH_PLUS_TOKEN:
                try:
                    response = requests.post(
                        "http://www.pushplus.plus/send",
                        json={
                            "token": PUSH_PLUS_TOKEN,
                            "title": f"{SCRIPT_NAME}统计报告",
                            "content": report,
                            "template": "markdown"
                        },
                        timeout=15
                    )
                    if response.status_code == 200:
                        self._log(f"📤 推送成功 | 消息ID: {response.json().get('data', '未知')}")
                    else:
                        self._log(f"⚠️ 推送失败 | HTTP状态码: {response.status_code}")
                except Exception as e:
                    self._log(f"🌐 推送异常: {str(e)}")
            else:
                self._log("⚠️ 未配置PUSH_PLUS_TOKEN，跳过推送")

            elapsed = (datetime.now() - self.analysis_start).total_seconds()
            self._log(f"✅ 分析完成 | 总耗时: {elapsed:.2f}秒")

        except KeyboardInterrupt:
            self._log("⏹ 用户中断操作")
            sys.exit(0)
        except Exception as e:
            self._log(f"💥 致命错误: {str(e)}")
            sys.exit(1)

if __name__ == "__main__":
    EarningsAnalyzer().run()